<template>
  <div class="raw-material-container">
    <el-card class="search-card">
      <!-- 搜索区域 -->
      <div class="search-area">
        <el-form :inline="true" :model="searchForm" class="search-form">
          <el-form-item label="原料类型：">
            <el-select v-model="searchForm.materialType" placeholder="请选择" clearable style="width: 200px">
              <el-option label="溶质" value="0" />
              <el-option label="溶剂" value="1" />
            </el-select>
          </el-form-item>
          <el-form-item label="原料名称：">
            <el-input v-model="searchForm.materialName" placeholder="请输入" clearable style="width: 200px" />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="commEvent.onSearch">查询</el-button>
            <el-button @click="commEvent.onReset">清空</el-button>
          </el-form-item>
        </el-form>
        <div class="action-buttons">
          <el-button type="primary" @click="commEvent.onImport" v-auth="'biz:sol:import'">导入</el-button>
          <el-button @click="commEvent.onClearSearch" v-auth="'biz:sol:clear'">清除</el-button>
        </div>
      </div>
    </el-card>

    <!-- 盘位展示区域 -->
    <div class="plate-container">
      <!-- 50ml区域 -->
      <div class="plate-column">
        <div class="column-header">50ml区域</div>

        <!-- 50ml上区 -->
        <div class="plate-area">
          <div class="plate-grid">
            <div
              v-for="position in leftTopPositions"
              :key="position.id"
              class="plate-item"
              :class="[`status-${position.status}`, { 'has-warning': position.hasWarning, 'is-highlight': position.isHighlight }]"
              @click="commEvent.onClickPosition(position)"
            >
              <div class="plate-icon">
                <div class="plate-visual">
                  <div
                    v-if="position.remainingStock > 0"
                    class="stock-remaining"
                    :style="{ height: position.remainingPercent + '%' }"
                  ></div>
                  <div
                    v-if="position.frozenStock > 0"
                    class="stock-frozen"
                    :style="{ height: position.frozenPercent + '%', bottom: position.remainingPercent + '%' }"
                  ></div>
                </div>
              </div>
              <div class="plate-label">盘位号{{ position.positionNo }}</div>
              <div class="plate-warning" v-if="position.hasWarning">!</div>
            </div>
          </div>
        </div>

        <!-- 50ml中区 -->
        <div class="plate-area">
          <div class="plate-grid">
            <div
              v-for="position in leftMiddlePositions"
              :key="position.id"
              class="plate-item"
              :class="[`status-${position.status}`, { 'has-warning': position.hasWarning, 'is-highlight': position.isHighlight }]"
              @click="commEvent.onClickPosition(position)"
            >
              <div class="plate-icon">
                <div class="plate-visual">
                  <div
                    v-if="position.remainingStock > 0"
                    class="stock-remaining"
                    :style="{ height: position.remainingPercent + '%' }"
                  ></div>
                  <div
                    v-if="position.frozenStock > 0"
                    class="stock-frozen"
                    :style="{ height: position.frozenPercent + '%', bottom: position.remainingPercent + '%' }"
                  ></div>
                </div>
              </div>
              <div class="plate-label">盘位号{{ position.positionNo }}</div>
              <div class="plate-warning" v-if="position.hasWarning">!</div>
            </div>
          </div>
        </div>

        <!-- 50ml下区 -->
        <div class="plate-area">
          <div class="plate-grid">
            <div
              v-for="position in leftBottomPositions"
              :key="position.id"
              class="plate-item"
              :class="[`status-${position.status}`, { 'has-warning': position.hasWarning, 'is-highlight': position.isHighlight }]"
              @click="commEvent.onClickPosition(position)"
            >
              <div class="plate-icon">
                <div class="plate-visual">
                  <div
                    v-if="position.remainingStock > 0"
                    class="stock-remaining"
                    :style="{ height: position.remainingPercent + '%' }"
                  ></div>
                  <div
                    v-if="position.frozenStock > 0"
                    class="stock-frozen"
                    :style="{ height: position.frozenPercent + '%', bottom: position.remainingPercent + '%' }"
                  ></div>
                </div>
              </div>
              <div class="plate-label">盘位号{{ position.positionNo }}</div>
              <div class="plate-warning" v-if="position.hasWarning">!</div>
            </div>
          </div>
        </div>
      </div>

      <!-- 150ml区域 -->
      <div class="plate-column">
        <div class="column-header">150ml区域</div>

        <!-- 150ml上区 -->
        <div class="plate-area">
          <div class="plate-grid">
            <div
              v-for="position in rightTopPositions"
              :key="position.id"
              class="plate-item"
              :class="[`status-${position.status}`, { 'has-warning': position.hasWarning, 'is-highlight': position.isHighlight }]"
              @click="commEvent.onClickPosition(position)"
            >
              <div class="plate-icon">
                <div class="plate-visual">
                  <div
                    v-if="position.remainingStock > 0"
                    class="stock-remaining"
                    :style="{ height: position.remainingPercent + '%' }"
                  ></div>
                  <div
                    v-if="position.frozenStock > 0"
                    class="stock-frozen"
                    :style="{ height: position.frozenPercent + '%', bottom: position.remainingPercent + '%' }"
                  ></div>
                </div>
              </div>
              <div class="plate-label">盘位号{{ position.positionNo }}</div>
              <div class="plate-warning" v-if="position.hasWarning">!</div>
            </div>
          </div>
        </div>

        <!-- 150ml中区 -->
        <div class="plate-area">
          <div class="plate-grid">
            <div
              v-for="position in rightMiddlePositions"
              :key="position.id"
              class="plate-item"
              :class="[`status-${position.status}`, { 'has-warning': position.hasWarning, 'is-highlight': position.isHighlight }]"
              @click="commEvent.onClickPosition(position)"
            >
              <div class="plate-icon">
                <div class="plate-visual">
                  <div
                    v-if="position.remainingStock > 0"
                    class="stock-remaining"
                    :style="{ height: position.remainingPercent + '%' }"
                  ></div>
                  <div
                    v-if="position.frozenStock > 0"
                    class="stock-frozen"
                    :style="{ height: position.frozenPercent + '%', bottom: position.remainingPercent + '%' }"
                  ></div>
                </div>
              </div>
              <div class="plate-label">盘位号{{ position.positionNo }}</div>
              <div class="plate-warning" v-if="position.hasWarning">!</div>
            </div>
          </div>
        </div>

        <!-- 150ml下区 -->
        <div class="plate-area">
          <div class="plate-grid">
            <div
              v-for="position in rightBottomPositions"
              :key="position.id"
              class="plate-item"
              :class="[`status-${position.status}`, { 'has-warning': position.hasWarning, 'is-highlight': position.isHighlight }]"
              @click="commEvent.onClickPosition(position)"
            >
              <div class="plate-icon">
                <div class="plate-visual">
                  <div
                    v-if="position.remainingStock > 0"
                    class="stock-remaining"
                    :style="{ height: position.remainingPercent + '%' }"
                  ></div>
                  <div
                    v-if="position.frozenStock > 0"
                    class="stock-frozen"
                    :style="{ height: position.frozenPercent + '%', bottom: position.remainingPercent + '%' }"
                  ></div>
                </div>
              </div>
              <div class="plate-label">盘位号{{ position.positionNo }}</div>
              <div class="plate-warning" v-if="position.hasWarning">!</div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 导入对话框 -->
    <el-dialog v-model="importDialogVisible" title="导入原料数据" width="600px" :close-on-click-modal="false">
      <div class="import-content">
        <div class="download-template">
          <el-button type="primary" link @click="commEvent.onDownloadTemplate">
            <el-icon><Download /></el-icon>
            下载原料导入模板
          </el-button>
        </div>
        <el-upload
          ref="uploadRef"
          class="upload-demo"
          drag
          :auto-upload="false"
          :on-change="commEvent.handleFileChange"
          :limit="1"
          accept=".xlsx,.xls"
        >
          <el-icon class="el-icon--upload"><upload-filled /></el-icon>
          <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
          <template #tip>
            <div class="el-upload__tip">只能上传 xlsx/xls 文件</div>
          </template>
        </el-upload>
      </div>
      <template #footer>
        <el-button @click="importDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="commEvent.onConfirmImport">确定导入</el-button>
      </template>
    </el-dialog>

    <!-- 导入失败提示对话框 -->
    <el-dialog v-model="failDialogVisible" title="导入结果" width="500px">
      <div class="import-result">
        <el-alert type="warning" :closable="false" show-icon>
          <template #title>
            <div>部分数据导入失败</div>
          </template>
        </el-alert>
        <div class="fail-list">
          <div class="fail-title">以下盘位号导入失败：</div>
          <div class="fail-items">
            <el-tag v-for="id in failedPositions" :key="id" type="danger" class="fail-tag">{{ id }}</el-tag>
          </div>
        </div>
      </div>
      <template #footer>
        <el-button type="primary" @click="failDialogVisible = false">确定</el-button>
      </template>
    </el-dialog>

    <!-- 盘位详情对话框 -->
    <sample-detail v-model="detailVisible" :position-data="currentPosition" @refresh="initPositions" />
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from "vue"
import { ElMessage, ElMessageBox, UploadUserFile } from "element-plus"
import { UploadFilled, Download } from "@element-plus/icons-vue"
import SampleDetail from "./components/SampleDetail.vue"
import {
  getMaterialList,
  clearAllMaterialData,
  downloadMaterialTemplate,
  importMaterialData,
  getPositionDetail,
  getAllPositionsList
} from "@/api/modules/material"

// 溶质数据接口
interface SoluteData {
  id: string
  name: string
  potency: string // 后端字段为potency
}

// 盘位数据接口
interface PositionData {
  id: number
  positionNo: string // 盘位号
  solutionType: string // 溶液类型
  materialType: string // 原料类型
  materialName: string // 原料名称
  totalCapacity: number // 总容量
  availableStock: number // 可用量
  remainingStock: number // 剩余量
  frozenStock: number // 冻结量
  status: "empty" | "normal" | "frozen" | "nodata" // 状态：空余、正常、冻结、无数据
  hasWarning: boolean // 是否有库存不足警告
  isHighlight: boolean // 是否高亮（查询匹配）
  remainingPercent: number // 剩余量百分比
  frozenPercent: number // 冻结量百分比
  solutes: SoluteData[] // 溶质列表
  // 后端返回的字段
  no?: number // 盘位号
  type?: number // 类型：0-溶质；1-溶剂
  recipeList?: Array<{ name: string; potency: number }> // 溶液配置集合
  remainAmount?: number // 可用量 (ml)
  freezeAmount?: number // 冻结量 (ml)
  cap?: number // 总容量 (ml)
  lowFlag?: boolean // 库存不足标识：true-库存不足
  selectedFlag?: boolean // 符合条件标识：true-符合条件
}

// 搜索表单
const searchForm = ref({
  materialType: "",
  materialName: ""
})

// 对话框状态
const detailVisible = ref(false) // 详情对话框
const importDialogVisible = ref(false) // 导入对话框
const failDialogVisible = ref(false) // 失败提示对话框
const uploadRef = ref() // 上传组件引用
const uploadFile = ref<UploadUserFile | null>(null) // 上传的文件

// 当前选中的盘位数据
const currentPosition = ref<PositionData | null>(null)

// 导入失败的盘位号列表
const failedPositions = ref<string[]>([])

// 所有盘位数据（108个）
const allPositions = ref<PositionData[]>([])

// 左侧50ml区域（54个盘位，9行6列）
// 排列规则：每行12个，前6个属于50ml区域
// 第1行: 1-6, 第2行: 13-18, 第3行: 25-30, ...
const leftPositions = computed(() => {
  return allPositions.value.filter(p => {
    const row = Math.ceil(p.id / 12) // 计算属于第几行（1-9）
    const posInRow = ((p.id - 1) % 12) + 1 // 计算在行内的位置（1-12）
    return posInRow <= 6 // 前6个属于50ml区域
  })
})

// 左侧50ml上区（1-3行，18个盘位）
const leftTopPositions = computed(() => {
  return leftPositions.value.filter(p => {
    const row = Math.ceil(p.id / 12) // 计算属于第几行（1-9）
    return row >= 1 && row <= 3
  })
})

// 左侧50ml中区（4-6行，18个盘位）
const leftMiddlePositions = computed(() => {
  return leftPositions.value.filter(p => {
    const row = Math.ceil(p.id / 12) // 计算属于第几行（1-9）
    return row >= 4 && row <= 6
  })
})

// 左侧50ml下区（7-9行，18个盘位）
const leftBottomPositions = computed(() => {
  return leftPositions.value.filter(p => {
    const row = Math.ceil(p.id / 12) // 计算属于第几行（1-9）
    return row >= 7 && row <= 9
  })
})

// 右侧150ml区域（54个盘位，9行6列）
// 排列规则：每行12个，后6个属于150ml区域
// 第1行: 7-12, 第2行: 19-24, 第3行: 31-36, ...
const rightPositions = computed(() => {
  return allPositions.value.filter(p => {
    const row = Math.ceil(p.id / 12) // 计算属于第几行（1-9）
    const posInRow = ((p.id - 1) % 12) + 1 // 计算在行内的位置（1-12）
    return posInRow > 6 // 后6个属于150ml区域
  })
})

// 右侧150ml上区（1-3行，18个盘位）
const rightTopPositions = computed(() => {
  return rightPositions.value.filter(p => {
    const row = Math.ceil(p.id / 12) // 计算属于第几行（1-9）
    return row >= 1 && row <= 3
  })
})

// 右侧150ml中区（4-6行，18个盘位）
const rightMiddlePositions = computed(() => {
  return rightPositions.value.filter(p => {
    const row = Math.ceil(p.id / 12) // 计算属于第几行（1-9）
    return row >= 4 && row <= 6
  })
})

// 右侧150ml下区（7-9行，18个盘位）
const rightBottomPositions = computed(() => {
  return rightPositions.value.filter(p => {
    const row = Math.ceil(p.id / 12) // 计算属于第几行（1-9）
    return row >= 7 && row <= 9
  })
})

// 初始化盘位数据
const initPositions = async (type?: number, name?: string) => {
  try {
    // 如果有查询条件，使用带参数的接口；否则使用无参数的接口
    const { data } = type !== undefined || name ? await getMaterialList(type || 0, name) : await getAllPositionsList()
    const positions: PositionData[] = []

    // 生成108个盘位
    for (let i = 1; i <= 108; i++) {
      // 查找后端返回的对应盘位数据
      const backendData = data?.find((item: any) => item.no === i)

      if (backendData) {
        // 有数据的盘位
        const total = backendData.cap || 0
        const remain = backendData.remainAmount || 0
        const freeze = backendData.freezeAmount || 0
        const used = total - remain - freeze

        // 计算百分比
        const remainPercent = total > 0 ? (remain / total) * 100 : 0
        const freezePercent = total > 0 ? (freeze / total) * 100 : 0

        // 判断状态
        let status: "empty" | "normal" | "frozen" | "nodata" = "normal"
        if (total === 0) {
          status = "nodata" // 蓝色-无数据
        } else if (remain === 0 && freeze === 0) {
          status = "empty" // 灰色-空余
        } else if (freeze > 0) {
          status = "frozen" // 黄色-有冻结量
        }

        positions.push({
          id: i,
          positionNo: String(backendData.no),
          solutionType: String(backendData.type ?? ""),
          materialType: "",
          materialName: "",
          totalCapacity: total,
          availableStock: remain,
          remainingStock: remain,
          frozenStock: freeze,
          status: status,
          hasWarning: backendData.lowFlag || false, // 使用后端的库存不足标识
          isHighlight: backendData.selectedFlag || false, // 使用后端的符合条件标识
          remainingPercent: remainPercent,
          frozenPercent: freezePercent,
          solutes: backendData.recipeList?.map((item: any, index: number) => ({
            id: `s-${index + 1}`,
            name: item.name || "",
            potency: String(item.potency || "")
          })) || [{ id: `s-1`, name: "", potency: "" }],
          // 保留后端字段
          no: backendData.no,
          type: backendData.type,
          recipeList: backendData.recipeList,
          remainAmount: backendData.remainAmount,
          freezeAmount: backendData.freezeAmount,
          cap: backendData.cap,
          lowFlag: backendData.lowFlag,
          selectedFlag: backendData.selectedFlag
        })
      } else {
        // 后端没有返回数据的盘位，显示为蓝色（无数据）
        positions.push({
          id: i,
          positionNo: `${i}`,
          solutionType: "",
          materialType: "",
          materialName: "",
          totalCapacity: i <= 54 ? 50 : 150,
          availableStock: 0,
          remainingStock: 0,
          frozenStock: 0,
          status: "nodata", // 蓝色-无数据
          hasWarning: false,
          isHighlight: false,
          remainingPercent: 0,
          frozenPercent: 0,
          solutes: [{ id: `s-1`, name: "", potency: "" }]
        })
      }
    }

    allPositions.value = positions
  } catch (error) {
    console.error("获取盘位数据失败:", error)
    // 失败时初始化为无数据状态（蓝色）
    const positions: PositionData[] = []
    for (let i = 1; i <= 108; i++) {
      positions.push({
        id: i,
        positionNo: `${i}`,
        solutionType: "",
        materialType: "",
        materialName: "",
        totalCapacity: i <= 54 ? 50 : 150,
        availableStock: 0,
        remainingStock: 0,
        frozenStock: 0,
        status: "nodata", // 蓝色-无数据
        hasWarning: false,
        isHighlight: false,
        remainingPercent: 0,
        frozenPercent: 0,
        solutes: [{ id: `s-1`, name: "", potency: "" }]
      })
    }
    allPositions.value = positions
  }
}

// 事件处理
const commEvent = {
  // 查询
  onSearch: async () => {
    const { materialType, materialName } = searchForm.value

    try {
      // 调用后端接口查询原料集合（无查询条件时相当于刷新所有数据）
      const type = materialType ? parseInt(materialType) : undefined

      // 直接调用 initPositions，传递查询参数，只调用一次接口
      await initPositions(type, materialName)

      // 统计高亮的盘位数量（后端返回的 selectedFlag 为 true）
      const highlightedCount = allPositions.value.filter(p => p.isHighlight).length

      if (!materialType && !materialName) {
        ElMessage.success(`数据刷新成功`)
      } else {
        ElMessage.success(`查询成功，找到 ${highlightedCount} 个匹配的盘位`)
      }
    } catch (error) {
      console.error("查询失败:", error)
      ElMessage.error("查询失败，请稍后重试")
    }
  },

  // 清空搜索条件
  onReset: () => {
    searchForm.value = {
      materialType: "",
      materialName: ""
    }
  },

  // 清除所有原料数据
  onClearSearch: async () => {
    try {
      await ElMessageBox.confirm("确定要清除所有原料数据吗？此操作不可恢复！", "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
        buttonSize: "default"
      })

      // 调用后端接口清除所有原料数据
      await clearAllMaterialData()

      // 清空所有盘位数据，清除后变为无数据状态（蓝色）
      allPositions.value.forEach(position => {
        position.solutionType = ""
        position.materialType = ""
        position.materialName = ""
        position.totalCapacity = 0 // 清除后总容量为0
        position.availableStock = 0
        position.remainingStock = 0
        position.frozenStock = 0
        position.status = "nodata" // 蓝色-无数据
        position.hasWarning = false
        position.isHighlight = false
        position.remainingPercent = 0
        position.frozenPercent = 0
        position.solutes = [{ id: `s-1`, name: "", potency: "" }]
      })

      // 清除搜索条件
      commEvent.onReset()

      ElMessage.success("已成功清除所有原料数据")
    } catch (error) {
      // 用户点击了取消
      console.log("取消清除操作")
    }
  },

  // 打开导入对话框
  onImport: () => {
    importDialogVisible.value = true
  },

  // 下载原料导入模板
  onDownloadTemplate: async () => {
    try {
      const blob = await downloadMaterialTemplate()
      const url = window.URL.createObjectURL(new Blob([blob]))
      const link = document.createElement("a")
      link.href = url
      link.setAttribute("download", "原料导入模板.xlsx")
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      window.URL.revokeObjectURL(url)
      ElMessage.success("模板下载成功")
    } catch (error) {
      console.error("下载模板失败:", error)
      ElMessage.error("下载模板失败，请稍后重试")
    }
  },

  // 文件选择变化
  handleFileChange: (file: UploadUserFile) => {
    uploadFile.value = file
  },

  // 确认导入
  onConfirmImport: async () => {
    if (!uploadFile.value) {
      ElMessage.warning("请先选择要导入的文件")
      return
    }

    try {
      // 调用后端接口导入数据
      const formData = new FormData()
      formData.append("file", uploadFile.value.raw!)
      const result = await importMaterialData(formData)

      // 检查导入结果
      if (result.data && result.data.failedIds && result.data.failedIds.length > 0) {
        // 有失败的数据
        failedPositions.value = result.data.failedIds
        failDialogVisible.value = true
        ElMessage.warning(`导入完成，但有 ${result.data.failedIds.length} 条数据导入失败`)
      } else {
        ElMessage.success("导入成功！")
      }

      // 关闭导入对话框
      importDialogVisible.value = false
      uploadFile.value = null
      uploadRef.value?.clearFiles()

      // 刷新数据
      initPositions()
    } catch (error: any) {
      console.error("导入失败:", error)
      // 检查是否有部分导入失败
      if (error.response?.data?.failedPositions && error.response.data.failedPositions.length > 0) {
        failedPositions.value = error.response.data.failedPositions
        failDialogVisible.value = true
      } else {
        ElMessage.error("导入失败，请检查文件格式")
      }
    }
  },

  // 点击盘位
  onClickPosition: async (position: PositionData) => {
    try {
      // 调用接口获取盘位详情
      const { data } = await getPositionDetail(position.id)
      // 合并后端返回的数据和当前盘位数据
      currentPosition.value = {
        ...position,
        ...data
      }
      detailVisible.value = true
    } catch (error) {
      console.error("获取盘位详情失败:", error)
      ElMessage.error("获取盘位详情失败")
    }
  }
}

// 页面加载时初始化数据
onMounted(() => {
  initPositions()
  // TODO: 实际应该从后端获取盘位数据
  // const data = await fetchPositionsData()
  // allPositions.value = data
})
</script>

<style lang="scss" scoped>
.raw-material-container {
  width: 100%;
  padding: 20px;
  background: #f5f7fa;
  .search-card {
    margin-bottom: 20px;
    .search-area {
      display: flex;
      align-items: center;
      justify-content: space-between;
      .search-form {
        display: flex;
        flex: 1;
        align-items: center;
        .el-form-item {
          margin-bottom: 0;
        }
      }
      .action-buttons {
        display: flex;
        gap: 10px;
      }
    }
  }
  .plate-container {
    display: flex;
    gap: 40px;
    justify-content: center;
    .plate-column {
      flex: 1;
      max-width: 600px;
      overflow: hidden;
      background: #ffffff;
      border-radius: 8px;
      box-shadow: 0 2px 8px rgb(0 0 0 / 10%);
      .column-header {
        padding: 16px;
        font-size: 18px;
        font-weight: 700;
        color: #303133;
        text-align: center;
        background: #f5f7fa;
        border-bottom: 2px solid #e4e7ed;
      }
    }
    .plate-area {
      border-bottom: 2px solid #e4e7ed;
      &:last-child {
        border-bottom: none;
      }
      .plate-grid {
        display: grid;
        grid-template-rows: repeat(3, 1fr);
        grid-template-columns: repeat(6, 1fr);
        gap: 12px;
        padding: 20px;
        background: #ffffff;
        .plate-item {
          position: relative;
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: center;
          padding: 8px;
          cursor: pointer;
          border-radius: 6px;
          transition: all 0.3s;
          &:hover {
            box-shadow: 0 4px 12px rgb(0 0 0 / 15%);
            transform: translateY(-2px);
          }
          .plate-icon {
            width: 50px;
            height: 50px;
            margin-bottom: 4px;
            .plate-visual {
              position: relative;
              width: 100%;
              height: 100%;
              overflow: hidden;
              background: linear-gradient(to bottom, #e0e0e0 0%, #bdbdbd 100%);
              border-radius: 8px 8px 12px 12px;
              .stock-remaining {
                position: absolute;
                right: 0;
                bottom: 0;
                left: 0;
                background: linear-gradient(to bottom, #81c784 0%, #66bb6a 100%);
                transition: height 0.3s;
              }
              .stock-frozen {
                position: absolute;
                right: 0;
                left: 0;
                background: linear-gradient(to bottom, #ffb74d 0%, #ffa726 100%);
                transition:
                  height 0.3s,
                  bottom 0.3s;
              }
            }
          }
          .plate-label {
            font-size: 12px;
            color: #666666;
            text-align: center;
          }
          .plate-warning {
            position: absolute;
            top: 2px;
            right: 2px;
            width: 18px;
            height: 18px;
            font-size: 12px;
            font-weight: bold;
            line-height: 18px;
            color: #ffffff;
            text-align: center;
            background: #f56c6c;
            border-radius: 50%;
          }

          // 无数据状态 - 蓝色
          &.status-nodata {
            background: #e3f2fd;
            border: 2px solid #90caf9;
            .plate-visual {
              background: linear-gradient(to bottom, #90caf9 0%, #64b5f6 100%);
            }
          }

          // 空余状态 - 灰色
          &.status-empty {
            background: #fafafa;
            border: 2px solid #e0e0e0;
          }

          // 正常状态 - 绿色
          &.status-normal {
            background: #f1f8e9;
            border: 2px solid #aed581;
          }

          // 冻结状态 - 黄色
          &.status-frozen {
            background: #fff8e1;
            border: 2px solid #ffd54f;
          }

          // 高亮状态（查询匹配）
          &.is-highlight {
            box-shadow: 0 0 20px rgb(64 158 255 / 60%);
            animation: glow 1.5s ease-in-out infinite;
          }
        }
      }
      .area-label {
        margin-top: 12px;
        font-size: 14px;
        font-weight: 500;
        color: #606266;
        text-align: center;
      }
    }
  }

  // 导入对话框内容
  .import-content {
    .download-template {
      display: flex;
      justify-content: flex-end;
      padding-bottom: 12px;
      margin-bottom: 16px;
      border-bottom: 1px solid #e4e7ed;
      .el-button {
        font-size: 14px;
      }
    }
  }

  // 导入结果样式
  .import-result {
    .fail-list {
      margin-top: 20px;
      .fail-title {
        margin-bottom: 12px;
        font-size: 14px;
        font-weight: 600;
        color: #606266;
      }
      .fail-items {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        .fail-tag {
          cursor: default;
        }
      }
    }
  }
}

// 发光动画
@keyframes glow {
  0%,
  100% {
    box-shadow: 0 0 20px rgb(64 158 255 / 60%);
  }
  50% {
    box-shadow: 0 0 30px rgb(64 158 255 / 90%);
  }
}

// 上传组件样式
:deep(.upload-demo) {
  .el-upload {
    width: 100%;
  }
  .el-upload-dragger {
    width: 100%;
  }
}
</style>
